package yuhuibear.poat.object.pipe;

import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import java.io.InputStream;
import java.io.OutputStream;
import java.sql.Connection;
import java.util.Date;
import java.util.Iterator;
import java.util.List;
import org.junit.After;
import org.junit.AfterClass;
import org.junit.Before;
import org.junit.BeforeClass;
import org.junit.Test;
import yuhuibear.poat.test.DatabaseTest;
import yuhuibear.poat.test.entity.PersonalProfile;
import yuhuibear.poat.test.entity.User;
import yuhuibear.poat.test.util.PoatTestSource;
import static org.junit.Assert.*;

/**
 * 
 * @author yuhui
 */
public class POATTest {

	private static POAT pm;

	public POATTest() {
	}

	@BeforeClass
	public static void setUpClass() throws Exception {
		pm = new POAT(new PoatTestSource(), "yuhuibear.poat.test.entity");
		pm.mapAllEntities(true);
		new DatabaseTest();
	}

	@AfterClass
	public static void tearDownClass() throws Exception {
	}

	@Before
	public void setUp() {
	}

	@After
	public void tearDown() {
	}

	/**
	 * Test of mapAllEntities method, of class POAT.
	 */
	@Test
	public void testMapAllEntities() throws Exception {
		System.out.println("mapAllEntities");
		String entityPackage = "yuhuibear.poat.test.entity";
		boolean clear = true;
		POAT instance = pm;
		int expResult = 11;
		if (!clear) {
			expResult = 1;
		}
		instance.scanEntity(entityPackage);
		int result = instance.mapAllEntities(clear);
		assertEquals(expResult, result);
	}

	@Test
	public void testSingleValue() throws Exception {
		ObjectAccessPipe pipe = pm.getPipe(Connection.TRANSACTION_READ_UNCOMMITTED);
		try {
			String[] conditions = new String[] { "Log.ownerId = ?" };
			String[] as = new String[] { "count(*) as number" };

			List<Integer> lst = pipe.list(as, Integer.class, conditions, 2);
			Iterator<Integer> itr = lst.iterator();
			int i = 0;
			while (itr.hasNext()) {
				System.out.println("[" + (i++) + "] : " + itr.next());
			}
			User user = new User();
			user.setId(4234235351L);
			user.setName("aaaaaaaaaa");
			pipe.add(user);
			pipe.commit();
			user.setId(4234555L);
			user.setName("222222222");
			pipe.add(user);
			User tu = pipe.get(User.class, new String[] { "id = ?" }, 4234555L);
			pipe.rollback();
			tu = pipe.get(User.class, new String[] { "id = ?" }, 4234555L);
			assertTrue(tu == null);
		} finally {
			pipe.close();
		}

	}

	@Test
	public void testBinaryValue() throws Exception {

		File file = new File(DatabaseTest.TestPic);
		InputStream is = new FileInputStream(file);
		ByteArrayOutputStream baos = new ByteArrayOutputStream();
		int cnt = 1;
		byte[] buf = new byte[4096];
		while (cnt > 0) {
			cnt = is.read(buf);
			if (cnt < 0) {
				break;
			}
			baos.write(buf, 0, cnt);
		}
		PersonalProfile pf = new PersonalProfile();
		pf.setName(file.getName());
		pf.setData(baos.toByteArray());

		ObjectAccessPipe pipe = pm.getPipe();
		try {
			pipe.add(pf);
			List<PersonalProfile> lst = pipe.list(PersonalProfile.class, null);
			Iterator<PersonalProfile> itr = lst.iterator();
			while (itr.hasNext()) {
				PersonalProfile pp = itr.next();
				System.out.println(pp);
				File f = new File("bin", pp.getName() + "_" + new Date().getTime());
				OutputStream out = new FileOutputStream(f);
				InputStream in = new ByteArrayInputStream(pp.getData());
				cnt = 1;
				try {
					while (true) {
						cnt = in.read(buf);
						if (cnt < 1) {
							break;
						}
						out.write(buf, 0, cnt);
					}
				} finally {
					if (out != null) {
						out.close();
					}
					if (in != null) {
						in.close();
					}
				}

			}
		} finally {
			pipe.close();
		}
	}

	@Test
	public void teatfLongArray() throws Exception {
		User u = new User();
		u.setName("array");
		u.setDatas(new Long[] { 1L, 2L, 222L, 4444L });

		ObjectAccessPipe pipe = pm.getPipe();
		try {
			pipe.add(u);
			pipe.commit();
		} finally {
			pipe.close();
		}
		assertNotNull(u.getId());
		try {
			pipe = pm.getPipe();
			User rslt = pipe.get(User.class, new String[] { "User.datas = ? " }, new Long[] { 1L, 2L, 222L, 4444L });
			assertEquals(u.getId(), rslt.getId());
		} finally {
			pipe.close();
		}
	}

}
